//tcp多线程并发员工管理系统服务器框架

#include "server_api.h"

//线程处理函数
void *pthread_fun(void *arg)
{
    MSG msg = *(MSG *)arg;
    int acceptfd = msg.acceptfd;
    struct sockaddr_in clientaddr = msg.clientaddr;

    //进行通信
    Staff_Data_TypeDef staff_dt;
    int len = sizeof(Staff_Data_TypeDef);
    ssize_t bytes;
    while(1)
    {
        //接收数据
        //如果发送方结束，recv就会返回0，所以需要将返回0的清空考虑一下
        if((bytes = recv(acceptfd, &staff_dt, len, 0)) == -1)
        {
            printf("recv error\n");
        }
        else if(bytes == 0)
        {
            printf("客户端[%s:%d]退出了\n",  inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
            close(acceptfd);
            pthread_exit(NULL);
        }

        printf("imode = %d\n",staff_dt.imode);
        printf("cmd=%x\n",staff_dt.cmd);
        printf("mode=%d\n",staff_dt.staff_info.mode);

		switch(staff_dt.imode){
		//case判断是root
        case 0:
			{
                //root登录
                if(staff_dt.cmd==0x10)
                {
                    login_root(&staff_dt,acceptfd);
                }
                switch(staff_dt.cmd)
				{
					//case判断按人名查找
                    case 0x51:
					{
                        printf("按人名查找\n");
						name_find(&staff_dt,acceptfd);
                        break;	
					}
                    //case判断查找所有
                    case 0x60:
                    {
                        each_all(&staff_dt,acceptfd);
                        break;
                    }
					//判断是修改操作,函数内部完成根据条件修改
                    case 0x40:
                    {
                        //管理员根据工号修改员工姓名
                        printf("case 0x40\n");
                        id_modify_info(&staff_dt,acceptfd);
                        break;
                    }
					//判断添加用户操作
                    case 0x20:
                    {
                        add_user(&staff_dt,acceptfd);
                        break;
                    }
					//判断删除用户操作
                    case 0x30:
                    {
                        delete_user(&staff_dt,acceptfd);
                        break;
                    }
					//判断查询历史记录操作
                    case 0x70:
                    {
                        search_histroy(&staff_dt,acceptfd);
                        break;
                    }
                    break;
				}
                break;
			}
        //case判断是user
        case 1:
			{
                //user登录
                if(staff_dt.cmd==0x10)
                {
                    login_user(&staff_dt,acceptfd);
                }
                switch(staff_dt.cmd)
				{
					//判断user查询操作
                    case 0x51:
                    {
                        user_search(&staff_dt,acceptfd);
                        break;
                    }
                    //判断user修改操作，函数内部完成id修改姓名
                    case 0x42:
                    {
                        user_id_modify_info(&staff_dt,acceptfd);
                        break;
                    }
                }
                break;
			}

		}





        /*
        if(strcmp(buf, "quit") == 0)
        {
            printf("客户端[%s:%d]退出了\n",  inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
            close(acceptfd);
            pthread_exit(NULL);
        }

        printf("client[%s:%d]: %s\n",  inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port), buf);

        strcat(buf, " *_*");

        //发送数据给客户端
        if(send(acceptfd, buf, N, 0) == -1)
        {
            ERRLOG("send error");
        }
        */
       
    }  
    exit(0);

}


int main(int argc, char const *argv[])
{

    int sockfd, acceptfd;
    struct sockaddr_in serveraddr, clientaddr;
    socklen_t addrlen = sizeof(serveraddr);
	
	

	//打开数据库
	if (sqlite3_open("staff_data", &db) != SQLITE_OK)
	{
		ERRLOG("sqlite3_open");
	}

    //创建数据库表
	create_datebase();

    //第一步：创建套接字
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        ERRLOG("socket error");
    }

    //设置端口复用
    int on  = 1;
    if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
    {
        ERRLOG("setsockopt error");
    }

    //第二步：填充服务器网络信息结构体
    serveraddr.sin_family = AF_INET;
    //serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    //serveraddr.sin_port = htons(atoi(argv[2]));
	serveraddr.sin_port = htons(atoi("8888"));
	serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    //第三步：将套接字与服务器网络信息结构体绑定
    if(bind(sockfd, (struct sockaddr *)&serveraddr, addrlen) == -1)
    {
        ERRLOG("bind error");
    }

    //第四步：将套接字设置为被动监听状态
    if(listen(sockfd, 5) == -1)
    {
        ERRLOG("listen error");
    }

    //使用多线程实现TCP并发服务器
    pthread_t thread;
    MSG msg;
    while(1)
    {
        //第五步：阻塞等待客户端的连接
        if((acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen)) == -1)
        {
            ERRLOG("accept error");
        }

        //获取客户端信息
        printf("[%s:%d]连接了\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));

        msg.acceptfd = acceptfd;
        msg.clientaddr = clientaddr;
        //只要有一个客户端跟服务器连接，服务器就创建一个子线程与之通信
        if(pthread_create(&thread, NULL, pthread_fun, &msg) != 0)
        {
            ERRLOG("pthread_create error");
        }

        //设置线程状态为分离态
        pthread_detach(thread);
    }


    return 0;
}
